﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Yinyue200.Sharp2D.Drawing
{
    public class ImageMakerWithIElement:IDisposable
    {
        public ImageMaker ImageMaker { get; protected set; }
        public ImageMakerWithIElement()
        {
            Windows.Graphics.Display.DisplayInformation.GetForCurrentView().DpiChanged += imageMakerWithIElement_DpiChanged;
        }
        public static void ClearElements(IList<IElement> items)
        {
            foreach(var one in items )
            {
                one.Dispose();
            }
            items.Clear();
        }
        /// <summary>
        /// 若要移除该类中的任何项，不要忘记 Dispose
        /// </summary>
        public IList<IElement> Elements
        {
            get; set;
        }
        public double Height { get; protected set; }
        public double Width { get; protected set; }
        public bool IsOpaque { get; protected set; }
        public bool EnableDxgi { get; protected set; }
        public void Draw(double height, double width, bool isOpaque, bool enableDxgi)
        {
            Height = height;
            Width = width;
            IsOpaque = isOpaque;
            EnableDxgi = enableDxgi;
            Draw(Windows.Graphics.Display.DisplayInformation.GetForCurrentView());
        }
        protected void Draw(Windows.Graphics.Display.DisplayInformation displayinfo)
        {
            ImageMaker?.Dispose();
            ImageMaker = new ImageMaker((int)(Width * displayinfo.RawPixelsPerViewPixel), (int)(Height * displayinfo.RawPixelsPerViewPixel), IsOpaque, EnableDxgi);
            ImageMaker.TextBlockImageSource.RenderTarget.DotsPerInch = new SharpDX.Size2F(displayinfo.LogicalDpi, displayinfo.LogicalDpi);
            redraw();
        }

        private void redraw()
        {
            ImageMaker.TextBlockImageSource.BeginDraw();
            ImageMaker.TextBlockImageSource.RenderTarget.Clear(ClearColor);
            foreach (var one in Elements)
            {
                one.Draw(this, ImageMaker.TextBlockImageSource.RenderTarget);
            }
            ImageMaker.TextBlockImageSource.EndDraw();
            SourceChanged?.Invoke(this, ImageMaker.Source);
        }

        public void Redraw()
        {
            if(ImageMaker!=null)
            {
                if(ImageMaker.TextBlockImageSource is ImageMaker.DxgiImageSource)
                {
                    redraw();
                }
            }
        }

        public SharpDX.Mathematics.Interop.RawColor4? ClearColor { get; set; }

        private void imageMakerWithIElement_DpiChanged(Windows.Graphics.Display.DisplayInformation sender, object args)
        {
            if (ImageMaker == null)
                return;
            Draw(sender);
        }

        public event Windows.Foundation.TypedEventHandler<ImageMakerWithIElement, Windows.UI.Xaml.Media.ImageSource> SourceChanged;

        #region IDisposable Support
        private bool disposedValue = false; // 要检测冗余调用

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    // TODO: 释放托管状态(托管对象)。
                }
                Windows.Graphics.Display.DisplayInformation.GetForCurrentView().DpiChanged -= imageMakerWithIElement_DpiChanged;
                if(Elements!=null)
                    ClearElements(Elements);
                ImageMaker?.Dispose();
                // TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。
                // TODO: 将大型字段设置为 null。

                disposedValue = true;
            }
        }

        // TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。
        ~ImageMakerWithIElement()
        {
            // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
            Dispose(false);
        }

        // 添加此代码以正确实现可处置模式。
        public void Dispose()
        {
            // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
            Dispose(true);
            // TODO: 如果在以上内容中替代了终结器，则取消注释以下行。
            GC.SuppressFinalize(this);
        }
        #endregion
    }
}
